using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
//
// DotNetNuke - http://www.dotnetnuke.com
// Copyright (c) 2002-2010
// by DotNetNuke Corporation
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System.Text.RegularExpressions;
using System.Web;
using DotNetNuke.Entities.Controllers;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Common;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Tabs;
using DotNetNuke.Entities.Host;
using DotNetNuke.Services.Localization;

namespace DotNetNuke.HttpModules
{

	public class UrlRewriteModule : IHttpModule
	{

		#region "Private Methods"

		private string FormatDomain(string URL, string ReplaceDomain, string WithDomain)
		{
			if (!string.IsNullOrEmpty(ReplaceDomain) && !string.IsNullOrEmpty(WithDomain)) {
				if (URL.IndexOf(ReplaceDomain) != -1) {
					URL = URL.Replace(ReplaceDomain, WithDomain);
				}
			}
			return URL;
		}

		private void RewriteUrl(HttpApplication app, ref string portalAlias)
		{
			HttpRequest Request = app.Request;
			HttpResponse Response = app.Response;
			string requestedPath = app.Request.Url.AbsoluteUri;

			portalAlias = "";

			//determine portal alias looking for longest possible match
			string myAlias = Globals.GetDomainName(app.Request, true);
			PortalAliasInfo objPortalAlias = default(PortalAliasInfo);
			do {
				objPortalAlias = PortalAliasController.GetPortalAliasInfo(myAlias);
				if ((objPortalAlias != null)) {
					portalAlias = myAlias;
					break;
				}

				int slashIndex = myAlias.LastIndexOf('/');
				if (slashIndex > 1) {
					myAlias = myAlias.Substring(0, slashIndex);
				} else {
					myAlias = "";
				}
			} while (!(myAlias.Length == 0));

			// save original url in context
			app.Context.Items.Add("UrlRewrite:OriginalUrl", app.Request.Url.AbsoluteUri);

			// Friendly URLs are exposed externally using the following format
			// http://www.domain.com/tabid/###/mid/###/ctl/xxx/default.aspx
			// and processed internally using the following format
			// http://www.domain.com/default.aspx?tabid=###&mid=###&ctl=xxx
			// The system for accomplishing this is based on an extensible Regex rules definition stored in /SiteUrls.config
			string sendTo = "";

			// save and remove the querystring as it gets added back on later
			// path parameter specifications will take precedence over querystring parameters
			string strQueryString = "";
			if ((!string.IsNullOrEmpty(app.Request.Url.Query))) {
				strQueryString = Request.QueryString.ToString();
				requestedPath = requestedPath.Replace(app.Request.Url.Query, "");
			}

			// get url rewriting rules 
			Config.RewriterRuleCollection rules = Config.RewriterConfiguration.GetConfig().Rules;

			// iterate through list of rules
			int intMatch = -1;
			for (int intRule = 0; intRule <= rules.Count - 1; intRule++) {
				// check for the existence of the LookFor value 
				string strLookFor = "^" + RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, rules[intRule].LookFor) + "$";
				Match objMatch = Regex.Match(requestedPath, strLookFor, RegexOptions.IgnoreCase);

				// if there is a match
				if ((objMatch.Success)) {
					// create a new URL using the SendTo regex value
					sendTo = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, Regex.Replace(requestedPath, strLookFor, rules[intRule].SendTo, RegexOptions.IgnoreCase));

					string strParameters = objMatch.Groups[2].Value;
					// process the parameters
					if ((strParameters.Trim().Length > 0)) {
						// split the value into an array based on "/" ( ie. /tabid/##/ )
						strParameters = strParameters.Replace("\\", "/");
						string[] arrParameters = strParameters.Split('/');
						string strParameterDelimiter = null;
						string strParameterName = null;
						string strParameterValue = null;
						// icreate a well formed querystring based on the array of parameters
						for (int intParameter = 1; intParameter <= arrParameters.Length - 1; intParameter++) {
							// ignore the page name 
							if (arrParameters[intParameter].IndexOf(".aspx", StringComparison.InvariantCultureIgnoreCase) == -1) {
								// get parameter name
								strParameterName = arrParameters[intParameter].Trim();
								if (strParameterName.Length > 0) {
									// add parameter to SendTo if it does not exist already  
									if (sendTo.IndexOf("?" + strParameterName + "=", StringComparison.InvariantCultureIgnoreCase) == -1 && sendTo.IndexOf("&" + strParameterName + "=", StringComparison.InvariantCultureIgnoreCase) == -1) {
										// get parameter delimiter
										if (sendTo.IndexOf("?") != -1) {
											strParameterDelimiter = "&";
										} else {
											strParameterDelimiter = "?";
										}
										sendTo = sendTo + strParameterDelimiter + strParameterName;
										// get parameter value
										strParameterValue = "";
										if ((intParameter < (arrParameters.Length - 1))) {
											intParameter += 1;
											if ((!string.IsNullOrEmpty(arrParameters[intParameter].Trim()))) {
												strParameterValue = arrParameters[intParameter].Trim();
											}
										}
										// add the parameter value
										if (strParameterValue.Length > 0) {
											sendTo = sendTo + "=" + strParameterValue;
										}
									}
								}
							}
						}
					}
					intMatch = intRule;
					break; // TODO: might not be correct. Was : Exit For
					// exit as soon as it processes the first match
				}
			}

			// add querystring parameters back to SendTo
			if (!string.IsNullOrEmpty(strQueryString)) {
				string[] arrParameters = strQueryString.Split('&');
				string strParameterName = null;
				// iterate through the array of parameters
				for (int intParameter = 0; intParameter <= arrParameters.Length - 1; intParameter++) {
					// get parameter name
					strParameterName = arrParameters[intParameter];
					if (strParameterName.IndexOf("=") != -1) {
						strParameterName = strParameterName.Substring(0, strParameterName.IndexOf("="));
					}
					// check if parameter already exists
					if (sendTo.IndexOf("?" + strParameterName + "=", StringComparison.InvariantCultureIgnoreCase) == -1 && sendTo.IndexOf("&" + strParameterName + "=", StringComparison.InvariantCultureIgnoreCase) == -1) {
						// add parameter to SendTo value
						if (sendTo.IndexOf("?") != -1) {
							sendTo = sendTo + "&" + arrParameters[intParameter];
						} else {
							sendTo = sendTo + "?" + arrParameters[intParameter];
						}
					}
				}
			}

			// if a match was found to the urlrewrite rules
			if (intMatch != -1) {
				if (rules[intMatch].SendTo.StartsWith("~")) {
					// rewrite the URL for internal processing
					RewriterUtils.RewriteUrl(app.Context, sendTo);
				} else {
					// it is not possible to rewrite the domain portion of the URL so redirect to the new URL
					Response.Redirect(sendTo, true);
				}

			} else {
				// Try to rewrite by TabPath
				string url = null;
				if (Globals.UsePortNumber() && ((app.Request.Url.Port != 80 && !app.Request.IsSecureConnection) || (app.Request.Url.Port != 443 && app.Request.IsSecureConnection))) {
					url = app.Request.Url.Host + ":" + app.Request.Url.Port.ToString() + app.Request.Url.LocalPath;
				} else {
					url = app.Request.Url.Host + app.Request.Url.LocalPath;
				}

				if (!string.IsNullOrEmpty(myAlias)) {
					if ((objPortalAlias != null)) {
						int portalID = objPortalAlias.PortalID;
						// Identify Tab Name 
						string tabPath = url;
						if ((tabPath.StartsWith(myAlias))) {
							tabPath = url.Remove(0, myAlias.Length);
						}

						// Default Page has been Requested
						if ((tabPath == "/" + Globals.glbDefaultPage.ToLower())) {
							return;
						}

						//Start of patch
						string CulturCode = string.Empty;

						Dictionary<string, Locale> dicLocales = LocaleController.Instance.GetLocales(portalID);
						if (dicLocales.Count > 1) {
							string[] splitUrl = app.Request.Url.ToString().Split('/');

							foreach (string CulturePart in splitUrl) {
								if (CulturePart.Length.Equals(5)) {
									foreach (KeyValuePair<string, Locale> key in dicLocales) {
										if (key.Key.ToLower().Equals(CulturePart.ToLower())) {
											CulturCode = key.Value.Code;
											tabPath = tabPath.Replace("/" + CulturePart, "");
											break; // TODO: might not be correct. Was : Exit For
										}
									}
								}
							}
						}

						// Check to see if the tab exists (if localization is enable, check for the specified culture)
						int tabID = TabController.GetTabByTabPath(portalID, tabPath.Replace("/", "//").Replace(".aspx", ""), CulturCode);

						// Check to see if neutral culture tab exists
						if ((tabID == Null.NullInteger && CulturCode.Length > 0)) {
							tabID = TabController.GetTabByTabPath(portalID, tabPath.Replace("/", "//").Replace(".aspx", ""), "");
						}

						//End of patch

						if ((tabID != Null.NullInteger)) {
							string sendToUrl = "~/" + Globals.glbDefaultPage + "?TabID=" + tabID.ToString();
							if (!CulturCode.Equals(string.Empty)) {
								sendToUrl = sendToUrl + "&language=" + CulturCode;
							}

							if ((!string.IsNullOrEmpty(app.Request.Url.Query))) {
								sendToUrl = sendToUrl + "&" + app.Request.Url.Query.TrimStart('?');
							}

							RewriterUtils.RewriteUrl(app.Context, sendToUrl);

							return;
						}
						tabPath = tabPath.ToLower();

						if ((tabPath.IndexOf('?') != -1)) {
							tabPath = tabPath.Substring(0, tabPath.IndexOf('?'));
						}

						if ((tabPath == "/login.aspx")) {
							//Get the Portal
							PortalInfo portal = new DotNetNuke.Entities.Portals.PortalController().GetPortal(portalID);

							if (portal.LoginTabId > Null.NullInteger && Globals.ValidateLoginTabID(portal.LoginTabId))
							{
								if ((!string.IsNullOrEmpty(app.Request.Url.Query))) {
									RewriterUtils.RewriteUrl(app.Context, "~/" + Globals.glbDefaultPage + "?TabID=" + portal.LoginTabId.ToString() + app.Request.Url.Query.TrimStart('?'));
								} else {
									RewriterUtils.RewriteUrl(app.Context, "~/" + Globals.glbDefaultPage + "?TabID=" + portal.LoginTabId.ToString());
								}
							} else {
								if ((!string.IsNullOrEmpty(app.Request.Url.Query))) {
									RewriterUtils.RewriteUrl(app.Context, "~/" + Globals.glbDefaultPage + "?portalid=" + portalID.ToString() + "&ctl=login&" + app.Request.Url.Query.TrimStart('?'));
								} else {
									RewriterUtils.RewriteUrl(app.Context, "~/" + Globals.glbDefaultPage + "?portalid=" + portalID.ToString() + "&ctl=login");
								}
							}
							return;
						}


						if ((tabPath == "/register.aspx")) {
							if ((!string.IsNullOrEmpty(app.Request.Url.Query))) {
								RewriterUtils.RewriteUrl(app.Context, "~/" + Globals.glbDefaultPage + "?portalid=" + portalID.ToString() + "&ctl=Register&" + app.Request.Url.Query.TrimStart('?'));
							} else {
								RewriterUtils.RewriteUrl(app.Context, "~/" + Globals.glbDefaultPage + "?portalid=" + portalID.ToString() + "&ctl=Register");
							}
							return;
						}

						if ((tabPath == "/terms.aspx")) {
							if ((!string.IsNullOrEmpty(app.Request.Url.Query))) {
								RewriterUtils.RewriteUrl(app.Context, "~/" + Globals.glbDefaultPage + "?portalid=" + portalID.ToString() + "&ctl=Terms&" + app.Request.Url.Query.TrimStart('?'));
							} else {
								RewriterUtils.RewriteUrl(app.Context, "~/" + Globals.glbDefaultPage + "?portalid=" + portalID.ToString() + "&ctl=Terms");
							}
							return;
						}

						if ((tabPath == "/privacy.aspx")) {
							if ((!string.IsNullOrEmpty(app.Request.Url.Query))) {
								RewriterUtils.RewriteUrl(app.Context, "~/" + Globals.glbDefaultPage + "?portalid=" + portalID.ToString() + "&ctl=Privacy&" + app.Request.Url.Query.TrimStart('?'));
							} else {
								RewriterUtils.RewriteUrl(app.Context, "~/" + Globals.glbDefaultPage + "?portalid=" + portalID.ToString() + "&ctl=Privacy");
							}
							return;
						}

						tabPath = tabPath.Replace("/", "//");
						tabPath = tabPath.Replace(".aspx", "");

						TabController objTabController = new TabController();
						TabCollection objTabs = default(TabCollection);
						if (tabPath.StartsWith("//host")) {
							objTabs = objTabController.GetTabsByPortal(Null.NullInteger);
						} else {
							objTabs = objTabController.GetTabsByPortal(portalID);
						}
						foreach (KeyValuePair<int, TabInfo> kvp in objTabs) {
							if ((kvp.Value.IsDeleted == false && kvp.Value.TabPath.ToLower() == tabPath)) {
								if ((!string.IsNullOrEmpty(app.Request.Url.Query))) {
									RewriterUtils.RewriteUrl(app.Context, "~/" + Globals.glbDefaultPage + "?TabID=" + kvp.Value.TabID.ToString() + "&" + app.Request.Url.Query.TrimStart('?'));
								} else {
									RewriterUtils.RewriteUrl(app.Context, "~/" + Globals.glbDefaultPage + "?TabID=" + kvp.Value.TabID.ToString());
								}
								return;
							}
						}
					}
				} else {
					// Should always resolve to something
					// RewriterUtils.RewriteUrl(app.Context, "~/" & glbDefaultPage)
					return;
				}
			}
		}

		#endregion

		#region "Public Properties"

		public string ModuleName {
			get { return "UrlRewriteModule"; }
		}

		#endregion

		public void Init(HttpApplication application)
		{
			application.BeginRequest += this.OnBeginRequest;
		}


		public void OnBeginRequest(object s, EventArgs e)
		{
			HttpApplication app = (HttpApplication)s;
			HttpServerUtility Server = app.Server;
			HttpRequest Request = app.Request;
			HttpResponse Response = app.Response;
			string requestedPath = app.Request.Url.AbsoluteUri;

			if (RewriterUtils.OmitFromRewriteProcessing(Request.Url.LocalPath)) {
				return;
			}

			//Carry out first time initialization tasks
			Initialize.Init(app);

			if (Request.Url.LocalPath.EndsWith("install.aspx", StringComparison.InvariantCultureIgnoreCase) || Request.Url.LocalPath.EndsWith("installwizard.aspx", StringComparison.InvariantCultureIgnoreCase) || Request.Url.LocalPath.EndsWith("captcha.aspx", StringComparison.InvariantCultureIgnoreCase)) {
				return;
			}

			// URL validation 
			// check for ".." escape characters commonly used by hackers to traverse the folder tree on the server
			// the application should always use the exact relative location of the resource it is requesting
			string strURL = Request.Url.AbsolutePath;
			string strDoubleDecodeURL = Server.UrlDecode(Server.UrlDecode(Request.RawUrl));
			if (Regex.Match(strURL, "[\\\\/]\\.\\.[\\\\/]").Success || Regex.Match(strDoubleDecodeURL, "[\\\\/]\\.\\.[\\\\/]").Success) {
				throw new HttpException(404, "Not Found");
			}
			try {
				//fix for ASP.NET canonicalization issues http://support.microsoft.com/?kbid=887459
				if ((Request.Path.IndexOf((char)92) >= 0 || System.IO.Path.GetFullPath(Request.PhysicalPath) != Request.PhysicalPath)) {
					throw new HttpException(404, "Not Found");
				}
			} catch (Exception ex) {
				//DNN 5479
				//request.physicalPath throws an exception when the path of the request exceeds 248 chars.
				//example to test: http://localhost/dotnetnuke_2/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/default.aspx
			}

			string DomainName = null;
			RewriteUrl(app, ref DomainName);

			//blank DomainName indicates RewriteUrl couldn't locate a current portal
			//reprocess url for portal alias if auto add is an option
			if (string.IsNullOrEmpty(DomainName) && CanAutoAddPortalAlias()) {
				DomainName = Globals.GetDomainName(app.Request, true);
			}

			// from this point on we are dealing with a "standard" querystring ( ie. http://www.domain.com/default.aspx?tabid=## )
			// if the portal/url was succesfully identified

			int TabId = -1;
			int PortalId = -1;

			string PortalAlias = null;
			PortalAliasInfo objPortalAliasInfo = null;

			// get TabId from querystring ( this is mandatory for maintaining portal context for child portals )
			if (!string.IsNullOrEmpty(Request.QueryString["tabid"])) {
				if (!Int32.TryParse(Request.QueryString["tabid"], out TabId)) {
					throw new HttpException(404, "Not Found");
				}
			}

			// get PortalId from querystring ( this is used for host menu options as well as child portal navigation )
			if (!string.IsNullOrEmpty(Request.QueryString["portalid"])) {
				if (!Int32.TryParse(Request.QueryString["portalid"], out PortalId)) {
					throw new HttpException(404, "Not Found");
				}
			}

			try {
				// alias parameter can be used to switch portals
				if ((Request.QueryString["alias"] != null)) {
					// check if the alias is valid
					string childAlias = Request.QueryString["alias"];
					if (!Globals.UsePortNumber())
					{
						childAlias = childAlias.Replace(":" + Request.Url.Port.ToString(), "");
					}
					if ((PortalAliasController.GetPortalAliasInfo(childAlias) != null)) {
						// check if the domain name contains the alias
						if (childAlias.IndexOf(DomainName) == 0) {
							// redirect to the url defined in the alias
							Response.Redirect(Globals.GetPortalDomainName(childAlias, Request, true), true);
						// the alias is the same as the current domain
						} else {
							PortalAlias = childAlias;
						}
					}
				}

				// PortalId identifies a portal when set
				if (PortalAlias == null) {
					if (PortalId != -1) {
						PortalAlias = PortalAliasController.GetPortalAliasByPortal(PortalId, DomainName);
					}
				}

				// TabId uniquely identifies a Portal
				if (PortalAlias == null) {
					if (TabId != -1) {
						// get the alias from the tabid, but only if it is for a tab in that domain
						PortalAlias = PortalAliasController.GetPortalAliasByTab(TabId, DomainName);
						if (PortalAlias == null || string.IsNullOrEmpty(PortalAlias)) {
							//if the TabId is not for the correct domain
							//see if the correct domain can be found and redirect it 
							objPortalAliasInfo = PortalAliasController.GetPortalAliasInfo(DomainName);
							if ((objPortalAliasInfo != null)) {
								if (app.Request.Url.AbsoluteUri.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase)) {
									strURL = "https://" + objPortalAliasInfo.HTTPAlias.Replace("*.", "");
								} else {
									strURL = "http://" + objPortalAliasInfo.HTTPAlias.Replace("*.", "");
								}
								if (strURL.IndexOf(DomainName, StringComparison.InvariantCultureIgnoreCase) == -1) {
									strURL += app.Request.Url.PathAndQuery;
								}
								Response.Redirect(strURL, true);
							}
						}
					}
				}

				// else use the domain name
				if (PortalAlias == null || string.IsNullOrEmpty(PortalAlias)) {
					PortalAlias = DomainName;
				}
				//using the DomainName above will find that alias that is the domainname portion of the Url
				//ie. dotnetnuke.com will be found even if zzz.dotnetnuke.com was entered on the Url
				objPortalAliasInfo = PortalAliasController.GetPortalAliasInfo(PortalAlias);
				if ((objPortalAliasInfo != null)) {
					PortalId = objPortalAliasInfo.PortalID;
				}

				// if the portalid is not known
				if (PortalId == -1) {
					bool autoAddPortalAlias = CanAutoAddPortalAlias();

					if (!autoAddPortalAlias && !Request.Url.LocalPath.EndsWith(Globals.glbDefaultPage, StringComparison.InvariantCultureIgnoreCase))
					{
						// allows requests for aspx pages in custom folder locations to be processed
						return;
					} else if (autoAddPortalAlias) {
						// use the host portal
						PortalAliasController objPortalAliasController = new PortalAliasController();
						PortalId = Host.HostPortalID;

						//the domain name was not found so try using the host portal's first alias
						if (PortalId > Null.NullInteger) {
							objPortalAliasInfo = new PortalAliasInfo();
							objPortalAliasInfo.PortalID = PortalId;
							objPortalAliasInfo.HTTPAlias = PortalAlias;
							objPortalAliasController.AddPortalAlias(objPortalAliasInfo);

							if (app.Request.Url.AbsoluteUri.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase)) {
								strURL = "https://" + objPortalAliasInfo.HTTPAlias.Replace("*.", "");
							} else {
								strURL = "http://" + objPortalAliasInfo.HTTPAlias.Replace("*.", "");
							}

							Response.Redirect(app.Request.Url.ToString(), true);
						}
					}
				}
			} catch (System.Threading.ThreadAbortException tex) {
			//Do nothing if Thread is being aborted - there are two response.redirect calls in the Try block
			} catch (Exception ex) {
				//'500 Error - Redirect to ErrorPage
				strURL = "~/ErrorPage.aspx?status=500&error=" + Server.UrlEncode(ex.Message);
				HttpContext.Current.Response.Clear();
				HttpContext.Current.Server.Transfer(strURL);
			}

			if (PortalId != -1) {
				// load the PortalSettings into current context
				PortalSettings _portalSettings = new PortalSettings(TabId, objPortalAliasInfo);
				app.Context.Items.Add("PortalSettings", _portalSettings);

				if (_portalSettings.PortalAliasMappingMode == PortalSettings.PortalAliasMapping.Redirect && !string.IsNullOrEmpty(_portalSettings.DefaultPortalAlias) && objPortalAliasInfo.HTTPAlias != _portalSettings.DefaultPortalAlias) {
					//Permanently Redirect
					Response.StatusCode = 301;
					Response.AppendHeader("Location", Globals.AddHTTP(_portalSettings.DefaultPortalAlias));
				}

				// manage page URL redirects - that reach here because they bypass the built-in navigation
				// ie Spiders, saved favorites, hand-crafted urls etc
				if (!string.IsNullOrEmpty(_portalSettings.ActiveTab.Url) && Request.QueryString["ctl"] == null && Request.QueryString["fileticket"] == null) {
					//Target Url
					string redirectUrl = _portalSettings.ActiveTab.FullUrl;

					if (_portalSettings.ActiveTab.PermanentRedirect) {
						//Permanently Redirect
						Response.StatusCode = 301;
						Response.AppendHeader("Location", redirectUrl);
					} else {
						//Normal Redirect
						Response.Redirect(redirectUrl, true);
					}
				}

				// manage secure connections
				if (Request.Url.AbsolutePath.EndsWith(".aspx", StringComparison.InvariantCultureIgnoreCase)) {
					// request is for a standard page
					strURL = "";
					// if SSL is enabled
					if (_portalSettings.SSLEnabled) {
						// if page is secure and connection is not secure
						if (_portalSettings.ActiveTab.IsSecure == true && Request.IsSecureConnection == false) {
							// switch to secure connection
							strURL = requestedPath.Replace("http://", "https://");
							strURL = FormatDomain(strURL, _portalSettings.STDURL, _portalSettings.SSLURL);
						}
					}
					// if SSL is enforced
					if (_portalSettings.SSLEnforced) {
						// if page is not secure and connection is secure
						if (_portalSettings.ActiveTab.IsSecure == false && Request.IsSecureConnection == true) {
							// check if connection has already been forced to secure
							if (Request.QueryString["ssl"] == null) {
								// switch to unsecure connection
								strURL = requestedPath.Replace("https://", "http://");
								strURL = FormatDomain(strURL, _portalSettings.SSLURL, _portalSettings.STDURL);
							}
						}
					}
					// if a protocol switch is necessary
					if (!string.IsNullOrEmpty(strURL)) {
						if (strURL.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase)) {
							// redirect to secure connection
							Response.Redirect(strURL, true);
						// when switching to an unsecure page, use a clientside redirector to avoid the browser security warning
						} else {
							Response.Clear();
							// add a refresh header to the response 
							Response.AddHeader("Refresh", "0;URL=" + strURL);
							// add the clientside javascript redirection script
							Response.Write("<html><head><title></title>");
							Response.Write("<!-- <script language=\"javascript\">window.location.replace(\"" + strURL + "\")</script> -->");
							Response.Write("</head><body></body></html>");
							// send the response
							Response.End();
						}
					}
				}

			} else {
				// alias does not exist in database
				// and all attempts to find another have failed
				//this should only happen if the HostPortal does not have any aliases
				//404 Error - Redirect to ErrorPage
				strURL = "~/ErrorPage.aspx?status=404&error=" + DomainName;
				HttpContext.Current.Response.Clear();
				HttpContext.Current.Server.Transfer(strURL);
			}

			if (app.Context.Items["FirstRequest"] != null) {
				app.Context.Items.Remove("FirstRequest");

				//Process any messages in the EventQueue for the Application_Start_FirstRequest event
				DotNetNuke.Services.EventQueue.EventQueueController.ProcessMessages("Application_Start_FirstRequest");
			}

		}

		private bool CanAutoAddPortalAlias()
		{
			bool autoAddPortalAlias = HostController.Instance.GetBoolean("AutoAddPortalAlias");
			autoAddPortalAlias = autoAddPortalAlias && new DotNetNuke.Entities.Portals.PortalController().GetPortals().Count == 1;
			return autoAddPortalAlias;
		}

		public void Dispose()
		{
		}

	}

}